﻿package com.flajaxian {
	
	import flash.events.*;
	import flash.display.Sprite;
	import flash.display.MovieClip;
	import flash.display.Bitmap;
	import flash.text.TextField;
	
	import flash.utils.*;
	
	import flash.display.BitmapData;
	import flash.display.Loader;
	
	import flash.display.LoaderInfo;
	import flash.net.navigateToURL;
    import flash.net.URLRequest;
    import flash.net.URLRequestMethod;
	
	public class FileUploader2 extends MovieClip
	{
		private var _initialized:Boolean = false;
		private var _params:Params;
		
		private var _browseBtn:ButtonGroup;
		private var _uploadBtn:ButtonGroup;
		private var _cancelBtn:ButtonGroup;
		
		private var _progressFore:Sprite;
		private var _progressBack:Sprite;
		private var _progressBorder:Sprite;
		private var _progressMask1:Sprite;
		private var _progressMask2:Sprite;
		
		private var _buttonsToLoadQueue:Array;
		private var _buttonsToLoadQueueIndex:int = -1;
		
		private var _initialProgressForeX:Number = 0;
		
		private var _mouseX:Number;
		private var _mouseY:Number;
		
		private var _files:FileReferenceCollection;
		
		
		public function FileUploader2(){
			this.addEventListener(Event.ADDED_TO_STAGE, this.onAddedToStage);
			this.stage.addEventListener(Event.MOUSE_LEAVE, this.onMouseLeftStage);
		}
		
		public function getFileUploadRequest(frh:FileReferenceHolder, index:int, isLast:Boolean):URLRequest{
			if(Params.instance.debug) t.obj(this._params.state, "getFileUploadRequest:"+this._params.targetUrl);
			var url:String = this._params.targetUrl;
			if(this._params.appendToUrlFileIndex){
				url = Util.endsWith(this._params.targetUrl,"&") ? this._params.targetUrl : this._params.targetUrl+"&";
				url += "__index="+index+"&__isLast="+isLast;
			}
			var req = new URLRequest(url);
			req.data = this._params.state;
			var fileKey:String = "F"+frh.id;
			if(Params.instance.statePerFile.hasOwnProperty(fileKey)){
				for(var each:String in Params.instance.statePerFile[fileKey]){
					req.data[each] = Params.instance.statePerFile[fileKey][each];
				}
			}
			req.method = URLRequestMethod.POST;
			return req;
		}
		
		private function onAddedToStage(evt:Event):void{
			if(!this._initialized){
				this._initialized = true;
				this.doInitialize();
			}
		}
		
		private function doInitialize():void{
			
			FlashJsManager.instance.addEventListener(FlashJsManager.INITIATE_FILE_UPLOAD, this.initiateFileUploadFromJs);
			FlashJsManager.instance.addEventListener(FlashJsManager.SET_VISIBILITY, this.setUiVisibility);
			FlashJsManager.instance.addEventListener(FlashJsManager.START_UPLOAD, this.startUpload);
			FlashJsManager.instance.addEventListener(FlashJsManager.ENABLED, this.enable);
			FlashJsManager.instance.addEventListener(FlashJsManager.DISABLED, this.disable);
			
			var incomingParams:Object = LoaderInfo(this.root.loaderInfo).parameters;
			
			
// ------------ fake parameters start here
			/*incomingParams = {
				id:"FileUploader1",
				allowedFileTypes:"All Files: *.*|Image Files (*.jpg)",
				imagesPath:"http://loc/HomeAssetTracker/images/flash/upload/",
				targetUrl:"http://loc/HomeAssetTracker/Test.aspx",
				browseBtnUrl:"Browse.gif",
				browseBtnOverUrl:"BrowseOver.gif",
				browseBtnPressUrl:"BrowsePress.gif",
				browseBtnDisableUrl:"BrowseDisabled.gif",
				uploadBtnUrl:"Upload.gif",
				uploadBtnOverUrl:"UploadOver.gif",
				uploadBtnPressUrl:"UploadPress.gif",
				uploadBtnDisableUrl:"UploadDisabled.gif",
				cancelBtnUrl:"Cancel.gif",
				cancelBtnOverUrl:"CancelOver.gif",
				cancelBtnPressUrl:"CancelPress.gif",
				//cancelBtnDisableUrl:"CancelDisabled.gif",
				//progressForeUrl:"ProgressFore.gif",
				browseBtnX:1,
				browseBtnY:15,
				browseBtnWidth:70,
				browseBtnHeight:24,
				uploadBtnX:70,
				uploadBtnY:15,
				uploadBtnWidth:75,
				uploadBtnHeight:24,
				cancelBtnX:139,
				cancelBtnY:15,
				cancelBtnWidth:75,
				cancelBtnHeight:24,
				progressX:1,
				progressY:1,
				progressWidth:202,
				progressHeight:11
			}*/
// ------------ fake parameters end here
			
			this._params = new Params( incomingParams );
			
			FlashJsManager.instance.markInitialized(); 
			
			if(Params.instance.debug) t.obj(incomingParams, "doInitialize");
			
			this._files = new FileReferenceCollection(this);
			this._files.addEventListener(FileReferenceCollection.FILES_SELECTED, this.onFilesSelected);
			this._files.addEventListener(FileReferenceCollection.FILE_QUEUE_ENDS, this.onFileQueueEnds);
			this._files.addEventListener(FileReferenceCollection.UPLOAD_PROGRESS, this.onUploadProgress);
			
			this.generateButtons();
			this.loadButtonContent();
			
			if(!this._params.enabled){
				this.disable(null);
			}
		}
		
		private function generateButtons():void{
			
			this._browseBtn = new ButtonGroup(this, this._params, "browseBtn");
			this._uploadBtn = new ButtonGroup(this, this._params, "uploadBtn");
			this._cancelBtn = new ButtonGroup(this, this._params, "cancelBtn");
			
			this._uploadBtn.setDisabled(true);
			this._cancelBtn.setDisabled(true);
			
			this._browseBtn.addEventListener(MouseEvent.CLICK, this.onBrowse);
			this._uploadBtn.addEventListener(MouseEvent.CLICK, this.onUpload);
			this._cancelBtn.addEventListener(MouseEvent.CLICK, this.onCancel);
			
			this._progressFore = this.generateSquare("progress");
			this._progressMask1 = this.generateSquare("progress", 1);
			this._progressFore.mask = this._progressMask1;
			
			this._progressBack = this.generateSquare("progress");
			this._progressMask2 = this.generateSquare("progress", 1);
			this._progressBack.mask = this._progressMask2;		
			
			this._progressBorder = this.generateProgressBorder();
			
			if(this._params.initiallyInvisible) this.uiVisibility(false);
			
			this._buttonsToLoadQueue = 
				[
				 {url:"browseBtnUrl", clip:this._browseBtn.on, def:"Browse_png"},
				 {url:"uploadBtnUrl", clip:this._uploadBtn.on, def:"Upload_png"},
				 {url:"cancelBtnUrl", clip:this._cancelBtn.on, def:"Cancel_png"},
				 {url:"progressBackUrl", clip:this._progressBack, def:"ProgressBack_png"},
				 {url:"progressForeUrl", clip:this._progressFore, def:"ProgressFore_png"},
				 {url:"browseBtnOverUrl", clip:this._browseBtn.over, def:"BrowseOver_png"},
				 {url:"uploadBtnOverUrl", clip:this._uploadBtn.over, def:"UploadOver_png"},
				 {url:"cancelBtnOverUrl", clip:this._cancelBtn.over, def:"CancelOver_png"},
				 {url:"browseBtnDisableUrl", clip:this._browseBtn.off, def:"BrowseDisabled_png"},
				 {url:"uploadBtnDisableUrl", clip:this._uploadBtn.off, def:"UploadDisabled_png"},
				 {url:"cancelBtnDisableUrl", clip:this._cancelBtn.off, def:"CancelDisabled_png"},
				 {url:"browseBtnPressUrl", clip:this._browseBtn.press, def:"BrowsePress_png"},
				 {url:"uploadBtnPressUrl", clip:this._uploadBtn.press, def:"UploadPress_png"},
				 {url:"cancelBtnPressUrl", clip:this._cancelBtn.press, def:"CancelPress_png"}
				 ];
				
		}
		
		private function onBrowse(evt:MouseEvent):void{
			if(this._browseBtn.isDisabled){ return; }
			if(Params.instance.debug) t.str("onBrowse");
			this._files.browse();
		}
		
		private function onUpload(evt:MouseEvent):void{
			if(this._uploadBtn.isDisabled){ return; }
			this.initiateUpload();
		}
		
		public function initiateUpload():void{
			if(Params.instance.debug) t.str("initiateUpload");
			this.setButtons(false, false, true);
			if(Params.instance.uploadRequiresJsConfirmation){
				FlashJsManager.instance.confirmUpload();
			}else{
				this._files.startUpload();
			}
		}
		
		private function onCancel(evt:MouseEvent):void{
			if(this._cancelBtn.isDisabled){ return; }
			this.initiateCancel();
		}
		
		public function initiateCancel():void{
			if(Params.instance.debug) t.str("initiateCancel");
			this.setButtons(true, false, false);
			this.resetProgressBar();
			this._files.cancel();
		}
		
		private function initiateFileUploadFromJs(evt:Object):void{
			if(this._files.count > 0){
				this._files.startUpload();
			}else{
				this.initiateCancel();
			}
		}
		
		private function startUpload(evt:FileUploaderEvent):void{
			if(this._files.count == 0){ return; } 
			this.setButtons(false, false, true);
			this._files.startUpload();
		}
		
		private function setUiVisibility(evt:FileUploaderEvent):void{
			this.initiateCancel();
			var bln:Boolean = Boolean(evt.state);
			
			this.uiVisibility(bln);
		}
		
		private function enable(evt:FileUploaderEvent):void{
			this.setButtons(true, false, false);
		}
		
		private function disable(evt:FileUploaderEvent):void{
			this._files.cancelAll(evt);
			this.setButtons(false, false, false);
		}
		
		//public function get browseBtn():Object{ return this._browseBtn; }
		
		private function uiVisibility(bln:Boolean):void{
			this._browseBtn.visible = 
				this._uploadBtn.visible =
					this._cancelBtn.visible = 
						this._progressFore.visible = 
							/*this._progressMask1.visible = */
								this._progressBack.visible = 
									/*this._progressMask2.visible = */
										this._progressBorder.visible = bln;
		}
		
		private function onFilesSelected(evt:FileUploaderEvent):void{
			if(Params.instance.debug) t.str("onFilesSelected", "state:"+evt.state);
			if(evt.state > 0){
				this.setButtons(true, true, true);
			}
			this.resetProgressBar();
		}
		
		private function resetProgressBar():void{
			this._progressBack.x = Params.instance.progressX;
		}
		
		private function onUploadProgress(evt:FileUploaderEvent):void{
			this._progressBack.x = 
				Params.instance.progressX + 
					(Params.instance.progressWidth * Number(evt.state));
		}
		
		private function onFileQueueEnds(evt:FileUploaderEvent):void{
			if(Params.instance.debug) t.str("onFileQueueEnds");
			this.setButtons(true, false, false);
			if(Params.instance.clearListAtEnd){
				this.resetProgressBar();
			}
		}
		
		private function setButtons(browse:Boolean, upload:Boolean, cancel:Boolean):void{
			this._browseBtn.setDisabled(!browse);
			this._uploadBtn.setDisabled(!upload);
			this._cancelBtn.setDisabled(!cancel);
		}
		
		private function onMouseLeftStage(me:Event):void{
			this._browseBtn.setOn();
			this._uploadBtn.setOn();
			this._cancelBtn.setOn();
		}
		
		private function generateSquare(prop:String, alphaVal:Number = 0):Sprite{
			return Util.generateSquare(this, this._params, prop, alphaVal)
		}
		
		private function loadButtonContent():void{
			var p:Object = this._params;
			p.ensureConsistency();
			this.loadOrGenerateNextImage();
		}
		
		private function generateImage(className:String):Bitmap{
			if(!this.loaderInfo.applicationDomain.hasDefinition(className)){
				return null;
			}
			var classReference:Class = this.loaderInfo.applicationDomain.getDefinition(className) as Class;
			return new Bitmap(new classReference(100,100));
		}
		
		private function loadOrGenerateNextImage():void{
			if(this._buttonsToLoadQueueIndex + 1 === this._buttonsToLoadQueue.length){
				this.loadingImagesQueueEnds();
			}else{
				this._buttonsToLoadQueueIndex++;
				this.loadOrGenerateImage(this._buttonsToLoadQueue[this._buttonsToLoadQueueIndex]);
			}
		}
		
		private function loadOrGenerateImage(info:Object):void{
			var p:Params = this._params;
			var url = p[info.url];
			if(Util.isNullOrEmpty(url)){
				var bitmap:Bitmap = this.generateImage(info.def);
				if(bitmap != null){
					info.clip.addChild(bitmap);
				}
			}else{
				var loader:Loader = new Loader();
				loader.load(new URLRequest(url));

				info.clip.addChild(loader);
			}
			this.loadOrGenerateNextImage();
		}
		
		private function loadingImagesQueueEnds():void{
			
		}
		
		
		
		private function generateProgressBorder():Sprite{
			var p:Params = this._params;
			var spr:Sprite = new Sprite();
			spr.graphics.lineStyle(p.progressBorderSize, p.progressBorderColor, p.progressBorderAlpha);
			spr.graphics.drawRect(0, 0, p.progressWidth, p.progressHeight);
			spr.x = p.progressX;
			spr.y = p.progressY;
			this.addChild(spr);
			return spr;
		}
		
		
	}
}